package linestrategy

import (
	"codejy/analysis/lineanalysis"
	"codejy/globalfunc"
	"codejy/structdef"
	"strings"
)

// 定义if条件表达式策略
type IfStrategy struct {
}

// 注册策略
func init() {
	RegisterStrategy(&IfStrategy{})
}

// 判断
func (f *IfStrategy) getId() int {
	return lineanalysis.If
}

func (f *IfStrategy) Execute(threadStore *structdef.ThreadStore) {
	IfHandle(threadStore)
}

// 处理if条件表达式
func IfHandle(threadStore *structdef.ThreadStore) {
	codes := threadStore.Codes
	currentPointer := threadStore.CurrentPoint
	length := len(codes)
	for i := currentPointer; i < length; i++ {
		code := codes[i]
		//获取if条件表达式的内容
		ifContent := code.LineContent
		//去掉if关键字 ,如果是if开头就去掉if,否则就去掉{
		if strings.HasPrefix(ifContent, "if") {
			ifContent = ifContent[2:]
		} else {
			ifContent = ifContent[1:]
		}
		//获取{位置
		index := strings.Index(ifContent, "{")
		//获取条件表达式
		ifCondition := ifContent[:index]
		//计算条件表达式的值
		ifConditionValue := globalfunc.ExecuteFunc("AssignmentStrategyMode", threadStore, ifCondition).(string)
		//判断条件表达式的值是否为真
		if ifConditionValue == "true" {
			endIndex := GetIfCodeBlockEnd(codes, i+1)
			//执行if语句块
			LineExecute(threadStore, i+1, endIndex)
			//设置当前执行指针
			currentPointer1 := GetIfCodeBlockAllEnd(codes, i+1)
			threadStore.CurrentPoint = currentPointer1
			break
		} else {
			//如果为假,判断是否有else if语句块,也就是最近一个}后面有内容的
			blockIndex := GetIfCodeBlockEnd(codes, i+1)
			//如果没有else if语句块,则执行else语句块
			if IsElse(codes[blockIndex].LineContent) {
				//获取else语句块
				endIndex := GetIfCodeBlockEnd(codes, blockIndex+1)
				LineExecute(threadStore, blockIndex+1, endIndex)
				//设置当前执行指针
				threadStore.CurrentPoint = endIndex
				break
			}
			//判断是否有else if语句块
			if IsElseIf(codes[blockIndex].LineContent) {
				//如果有else if语句块,则执行else if语句块的条件
				i = blockIndex - 1
				continue
			}
			//既没有else语句块,也没有else if语句块,则直接跳过if语句块
			threadStore.CurrentPoint = blockIndex
			break
		}
	}
}

// 获取下一个}的位置
func GetIfCodeBlockEnd(codeBlocks []structdef.LineCodeDefinition, startIndex int) int {
	length := len(codeBlocks)
	var ifNum = 1
	var j int
	for j = startIndex; j < length; j++ {
		ifBlockCode := codeBlocks[j]
		lineContent := ifBlockCode.LineContent
		//截取if语句块的内容
		if strings.HasPrefix(lineContent, "}") {
			ifNum--
		}
		if ifNum == 0 {
			break
		}
		if strings.HasSuffix(lineContent, "{") {
			ifNum++
		}
	}
	return j
}

// 获取最后一个}的位置
func GetIfCodeBlockAllEnd(codeBlocks []structdef.LineCodeDefinition, startIndex int) int {
	length := len(codeBlocks)
	var ifNum = 1
	var j int
	for j = startIndex; j < length; j++ {
		ifBlockCode := codeBlocks[j]
		lineContent := ifBlockCode.LineContent
		//截取if语句块的内容
		if strings.HasPrefix(lineContent, "}") {
			ifNum--
		}
		if ifNum == 0 {
			//判断是否有else if语句块
			if IsElseIf(codeBlocks[j].LineContent) || IsElse(codeBlocks[j].LineContent) {
				//如果有else if语句块就继续往下找
				ifNum++
				continue
			}

			break
		}
		if strings.HasSuffix(lineContent, "{") {
			ifNum++
		}
	}
	return j
}

// 判断是否是else if{
func IsElseIf(lineContent string) bool {
	//判断开头是否是} ,结尾是否是{
	if !strings.HasPrefix(lineContent, "}") || !strings.HasSuffix(lineContent, "{") {
		return false
	}
	//去掉}和{ ,判断中间是否有内容
	lineContent = lineContent[1 : len(lineContent)-1]
	if len(lineContent) == 0 {
		return false
	}
	return true
}

// 判断是否是else{
func IsElse(lineContent string) bool {
	//判断开头是否是} ,结尾是否是{
	if !strings.HasPrefix(lineContent, "}") || !strings.HasSuffix(lineContent, "{") {
		return false
	}
	//去掉}和{ ,判断中间是否是else
	lineContent = lineContent[1 : len(lineContent)-1]
	if lineContent != "else" {
		return false
	}
	return true
}
